import { useEffect, useRef } from "react";
// 从 rc-util 库导入动态 CSS 操作工具
// removeCSS - 移除指定标识的样式表
// updateCSS - 创建/更新指定标识的样式表
import { removeCSS, updateCSS } from "rc-util/lib/Dom/dynamicCSS";
import { theme } from "antd"; // 导入 Ant Design 主题上下文

// 视图过渡动画的全局样式配置
// 使用 ::view-transition-old 和 ::view-transition-new 伪元素控制主题切换动画
const viewTransitionStyle = `
/* 禁用默认动画并设置混合模式 */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal; // 混合模式设置为正常，确保动画不会影响其他元素的透明度
}

/* 暗色主题切换时的层级控制 */
.dark::view-transition-old(root) {
  z-index: 1;  // 旧视图在下层
}
.dark::view-transition-new(root) {
  z-index: 999; // 新视图在上层
}

/* 默认亮色主题层级控制 */
::view-transition-old(root) {
  z-index: 999; // 旧视图在上层
}
::view-transition-new(root) {
  z-index: 1;   // 新视图在下层
}
`;
const useThemeAnimation = () => {
  // 解构token对象，获取colorBgElevated属性
  // colorBgElevated是Ant Design主题中的一个属性，用于表示元素的背景颜色
  const {
    token: { colorBgElevated },
  } = theme.useToken();
  const animateRef = useRef<{ colorBgElevated: string }>({ colorBgElevated });

  const startAnimationTheme = (clipPath: string[], isDark: boolean) => {
    updateCSS(
      `* {
        transition: none !important;
      }`,
      "disable-transition"
    );

    document.documentElement
      .animate(
        {
          clipPath: isDark ? [...clipPath].reverse() : clipPath,
        },
        {
          duration: 500,
          easing: "ease-in",
          pseudoElement: isDark
            ? "::view-transition-old(root)"
            : "::view-transition-new(root)",
        }
      )
      .addEventListener("finish", () => {
        removeCSS("disable-transition");
      });
  };

  const toggleAnimationTheme = (event: React.MouseEvent<HTMLElement, MouseEvent>, isDark: boolean) => {
    // 检查浏览器是否支持视图过渡API和事件对象是否存在
    if (!(event && typeof document.startViewTransition === "function")) {
      return;
    }
    const time = Date.now();
    // 获取点击事件坐标
    // clientX 和 clientY 是鼠标点击位置相对于视口的坐标
    const x = event.clientX;
    const y = event.clientY;
    // 计算最大扩散半径（覆盖整个视口）
    // innerWidth 和 innerHeight 是浏览器窗口的内部尺寸
    // Math.max(x, innerWidth - x) 计算从点击位置到窗口边缘的最大水平距离
    // Math.max(y, innerHeight - y) 计算从点击位置到窗口边缘的最大垂直距离
    // Math.hypot 计算从点击位置到窗口边缘的最大距离（即最大扩散半径）
    const endRadius = Math.hypot(
      Math.max(x, innerWidth - x),
      Math.max(y, innerHeight - y)
    );
    // 临时修改颜色方案强制触发重绘, 这是为了确保浏览器在应用过渡动画之前正确识别颜色方案的变化
    // color-scheme 是 CSS 属性，用于指定浏览器应该使用的颜色方案（深色或浅色）
    updateCSS(
      `[data-prefers-color='dark'] {
        color-scheme: light !important;
      }
      [data-prefers-color='light'] {
        color-scheme: dark !important;
      }`,
      "color-scheme"
    );
    // 启动视图过渡动画
    // startViewTransition 是浏览器提供的 API，用于启动视图过渡动画
    // 该 API 接受一个回调函数，该回调函数会在视图过渡动画开始时被调用
    // 该回调函数返回一个 Promise，当视图过渡动画结束时会被解析
    document.startViewTransition(async () => {
        // 等待主题色变更完成（通过ref对比, 避免重复触发）
        // 这里使用了一个简单的循环，不断检查主题色是否发生变化
        // 如果主题色发生变化，则继续等待，否则退出循环
        while (colorBgElevated === animateRef.current.colorBgElevated) {
          await new Promise<void>((resolve) => setTimeout(resolve, 1000 / 60));
        }
        // 切换根节点类名（dark/light）
        const root = document.documentElement;
        root.classList.remove(isDark ? "dark" : "light");
        root.classList.add(isDark ? "light" : "dark");
      })
      .ready.then(() => {
        // 计算圆形路径（从点击位置开始，扩散到最大半径）
        const clipPath = [
          `circle(0px at ${x}px ${y}px)`,
          `circle(${endRadius}px at ${x}px ${y}px)`,
        ];
        // 动画完成后清理临时样式
        removeCSS("color-scheme");
        // 动画完成后清理临时样式
        startAnimationTheme(clipPath, isDark);
      });
  };

  // 注入视图过渡样式
  // 检查浏览器是否支持视图过渡API
  useEffect(() => {
    if (typeof document.startViewTransition === "function") {
      updateCSS(viewTransitionStyle, "view-transition-style");
    }
  }, []); // 空依赖数组表示只运行一次

  // 同步最新主题色到ref
  useEffect(() => {
    if (colorBgElevated !== animateRef.current.colorBgElevated) {
      animateRef.current.colorBgElevated = colorBgElevated;
    }
  }, [colorBgElevated]); // 依赖主题色变化

  return toggleAnimationTheme;
};

export default useThemeAnimation;
